📝 我的笔记

还没有笔记

选中页面文字后点击「高亮」按钮添加

1 C 语言中的字符串

📜 原文
📖 逐步解释
∑ 公式拆解
💡 数值示例
⚠️ 易错点
📝 总结
🎯 存在目的
🧠 直觉心智模型
💭 直观想象

1C 语言中的字符串

COMS W3157

Dr. Borowski 大学

2字符数组

char mystring[] = "hello";上创建了以下数组

| ' h ' | ' e ' | ' l ' | ' l ' | ' o ' | ' $\backslash 0^{\prime}$ |

| :---: | :---: | :---: | :---: | :---: | :---: |

3字符数组

| $' \mathrm{~h} '$ | $' \mathrm{e}^{\prime}$ | $' \mathrm{l}^{\prime}$ | $' \mathrm{l}^{\prime}$ | $' \mathrm{o}^{\prime}$ | $' \backslash \mathrm{o}^{\prime}$ |

| :---: | :---: | :---: | :---: | :---: | :---: |

也可以被认为是

| 104 | 101 | 108 | 108 | 111 | 0 |

| :--- | :--- | :--- | :--- | :--- | :--- |

4库字符串函数

5库字符串函数

让我们填入这个函数,使其返回字符串 s 的长度:

```

int strlen(const char *s){

int i = 0;

while (___) {

i++;

}

return

```

$\_\_\_\_$

```

;

}

```

6库字符串函数

让我们填入这个函数,使其返回字符串 s 的长度:

```

int strlen(const char *s) {

int i = 0;

while (*s++) {

i++;

}

return i;

}

```

7库字符串函数

让我们填入这个函数,使其将字符串 s 复制到字符串 t 中:

```

char strcpy(char t, const char *s) {

int len = __;

for (int i = 0; i <= len; i++) {

;

}

return t;

}

```

8库字符串函数

让我们填入这个函数,使其将字符串 s 复制到字符串 t 中:

```

char strcpy(char t, const char *s) {

int len = strlen(s);

for (int i = 0; i <= len; i++) {

t[i] = s[i];

}

return t;

}

```

9库字符串函数

让我们填入这个函数,使其将字符串 s 复制到一个堆分配缓冲区中:

```

char strdup(const char s) {

char *res = malloc(____);

strcpy(____);

return res;

}

```

大学

10库字符串函数

让我们填入这个函数,使其将字符串 s 复制到一个堆分配缓冲区中:

```

char strdup(const char s){

char *res = malloc(strlen(s) + 1);

strcpy(res, s);

return res;

}

```

注意调用者稍后必须 free 分配的 char *

11内存中的字符串

12栈分配的字符串

代码片段

```

char mystring[] = "abc";

```

等同于

```

char mystring[4] = {'a', 'b', 'c', '\0'};

```

它创建了一个基础的栈分配数组,这意味着 &mystring == &mystring[0],也就是说,数组名退化为指向数组第一个元素的指针

13栈分配的字符串数组

char stringsl[3][6] = { "Hello", "Hi", "Bye" }; 被分配为一个由 $3 \times 6$字符组成的一维数组

| ' H ' | 'e' | 'l' | 'l' | '。' | '\0' | 'H' | 'i' | '\0' | | | | 'B' | 'y' | 'e' | '\0' | | |

| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |

最长的字符串是 5 个字符 +1 个空终止符,总共 6 个字符。较短的字符串也消耗 6 个字符,尽管最初在空终止符之后的数组索引中可能存在随机字符

14只读字符串

代码片段

```

char *mystring = "abc";

```

不会创建一个栈分配字符数组。相反,该数组被分配在只读数据段中,贯穿程序的整个生命周期。

在这个例子中,mystring 是一个指向存储该字符串内存地址栈分配指针。大学

15只读字符串

创建只读字符串的一个后果是它们是……只读的。考虑这段代码:

```

char *mystring = "abc";

mystring[0] = 'b'; // 运行时错误

```

这里我们只是尝试创建并修改这样一个字符串。在栈分配字符串中,这完全没问题,但上面的代码片段将导致分段错误,因为 mystring 是一个指向只读数据指针

16命令行参数

17命令行参数

代码片段 char *array[] = {"a.bc", "defg", "hijkl"};内存中是这样存储的:

array:

| ${ }^{\prime} \mathrm{a}^{\prime}$ | ${ }^{\prime} \mathrm{b}^{\prime}$ | ${ }^{\prime} \mathrm{c}^{\prime}$ | ' $\backslash \mathrm{o}^{\prime}$ |

| :--- | :--- | :--- | :--- |

| 'd' | 'e' | 'f' | 'g' | ' \O' |

| :---: | :---: | :---: | :---: | :---: |

| ' h ' | ' i ' | ' j ' | ' $\mathrm{k}^{\prime}$ | 'l' | ' \n' |

| :--- | :--- | :--- | :--- | :--- | :--- |

18命令行参数

类似地,. /ex abc defg内存中这样存储其参数

19命令行参数

20命令行参数

让我们填入这段代码,在新行上打印所有命令行参数

```

int main(int argc, char **argv){

for (int i = 1; i < ___ ; i++) {

printf("%s\n", ___);

}

}

```

21命令行参数

让我们填入这段代码,在新行上打印所有命令行参数

```

int main(int argc, char **argv){

for (int i = 1; i < argc; i++) {

printf("%s\n", argv[i]);

}

}

```

22命令行参数

让我们填入这段代码,在不使用 argc 且不使用下标的情况下,在新行上打印所有命令行参数

```

int main(int argc, char **argv){

;

while (___) {

printf("%s\n", ___);

}

}

```

23命令行参数

让我们填入这段代码,在不使用 argc 且不使用下标的情况下,在新行上打印所有命令行参数

```

int main(int argc, char **argv){

argv++;

wh 跳过打印 argv[0]。

while (*argv) {

printf("%s\n", *argv++);

}

}

```